package com.dragons.dragonsvf.utils.secret;

import javax.crypto.Cipher;
import java.security.*;
import java.util.Base64;

public class RSAEncryption {

    private static final String RSA = "RSA";
    // 安全字符白名单（字母数字及指定符号）
    private static final String SAFE_CHARS = "*-._&%#@!$+=|";

    public static void main(String[] args) throws Exception {
        // 生成密钥对（推荐至少2048位）
        KeyPair keyPair = generateKeyPair(512);  // 测试使用1024位，生产环境建议2048+
        System.out.println("keyPair:: "+keyPair);
        // 加密测试
        //String plainText = "VIa54nSipPHD8HqiQjB-sQ__";
        String plainText = "dragons1314127";
        String encrypted = encrypt(plainText, keyPair.getPublic());
        System.out.println("加密结果：" + encrypted);

        // 解密测试
        String decrypted = decrypt(encrypted, keyPair.getPrivate());
        System.out.println("解密结果：" + decrypted);
    }

    /**
     * 生成密钥对（推荐2048位以上）
     * @param keySize 密钥长度（至少512）
     */
    public static KeyPair generateKeyPair(int keySize) throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(RSA);
        keyPairGen.initialize(keySize);
        return keyPairGen.generateKeyPair();
    }

    /**
     * 加密方法（自动压缩+安全编码）
     * @param plainText 明文（建议不超过密钥长度/8 - 11）
     */
    public static String encrypt(String plainText, PublicKey publicKey) throws Exception {
        // 数据压缩（缩短明文长度）
        byte[] compressed = compress(plainText.getBytes());

        // RSA加密
        Cipher cipher = Cipher.getInstance(RSA);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encrypted = cipher.doFinal(compressed);

        // 安全Base64编码
        return safeEncode(encrypted);
    }

    /**
     * 解密方法
     */
    public static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
        // 安全Base64解码
        byte[] encrypted = safeDecode(encryptedText);

        // RSA解密
        Cipher cipher = Cipher.getInstance(RSA);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decrypted = cipher.doFinal(encrypted);

        // 数据解压缩
        return new String(decompress(decrypted));
    }

    /**
     * 安全编码（替换特殊字符）
     */
    private static String safeEncode(byte[] data) {
        String base64 = Base64.getUrlEncoder().withoutPadding().encodeToString(data);
        // 二次过滤确保只包含安全字符
        return filterSpecialChars(base64);
    }

    /**
     * 安全解码（还原特殊字符）
     */
    private static byte[] safeDecode(String text) {
        String restored = restoreSpecialChars(text);
        return Base64.getUrlDecoder().decode(restored);
    }

    /**
     * 过滤非安全字符（白名单机制）
     */
    private static String filterSpecialChars(String str) {
        StringBuilder sb = new StringBuilder();
        for (char c : str.toCharArray()) {
            if (Character.isLetterOrDigit(c) || SAFE_CHARS.indexOf(c) != -1) {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 还原可能被过滤的字符（需要与过滤规则对应）
     */
    private static String restoreSpecialChars(String filtered) {
        // 如果过滤时没有修改字符，直接返回原始字符串
        return filtered;
    }

    /**
     * 简单压缩（适用于短文本）
     */
    private static byte[] compress(byte[] data) {
        // 实际生产建议使用GZIP等压缩算法
        return data;  // 示例简化处理
    }

    /**
     * 简单解压
     */
    private static byte[] decompress(byte[] data) {
        return data;  // 示例简化处理
    }
}